package com.example.iorder.reservation;

import java.util.ArrayList;
import java.util.Calendar;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.domain.RestaurantTable;
import com.example.iorder.R;
import com.example.iorder.config.Config;
import com.example.iorder.util.HTTPClient;
import com.example.iorder.util.TextFormatter;

public class TableReservation extends ListActivity implements OnScrollListener {
	ListTableAdapter adapter;
	private ProgressDialog progress;
	private Activity messageContext;
	private ResultsItemHolder selectedTable;
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        messageContext = this;
        setContentView(R.layout.reservation_tables);
        
        // Show loading indicator
        progress = new ProgressDialog(messageContext);
        progress.setTitle(getResources().getString(R.string.loading_title));
        progress.setMessage(getResources().getString(R.string.loading_message));
        progress.show();
        
        Bundle reservationInfo = getIntent().getExtras();
        final int restaurantId = reservationInfo.getInt(getResources().getString(R.string.key_restaurant_id));
        Calendar reservationDate;
        int[] selectedDateArray = reservationInfo.getIntArray("selectedDate");
		int selectedYear = selectedDateArray[0];
		int selectedMonth = selectedDateArray[1];
		int selectedDay = selectedDateArray[2];
		int selectedHour = selectedDateArray[3];
		int selectedMinute = selectedDateArray[4];
		reservationDate = Calendar.getInstance();
		reservationDate.clear();
		reservationDate.set(selectedYear, selectedMonth, selectedDay, selectedHour, selectedMinute);
		final String formattedDate = TextFormatter.formatDateToString(reservationDate);
		final String formattedTime = TextFormatter.formatTimeToString(reservationDate);
        
        
        // Start another thread to search for restaurants
        new Thread() {
        	public void run() {
        		Message msg = new Message();
        		String path = "";
        		HTTPClient httpClient = null;
        		String searchResult = "";
        		
        		try {
        			path = "/tablereservations?restaurantid=" + restaurantId + "&"
        					+ "seats=4&"
        					+ "date=" + formattedDate + "&"
        					+ "time=" + formattedTime;
        			httpClient = new HTTPClient(getBaseContext());
        			searchResult = httpClient.sendGETRequest(Config.IORDER_SERVER, path);
        			
        			msg.getData().putString("searchResult", searchResult);
        			searchOutputHandler.sendMessage(msg);
        		} catch (Exception e) {
        			msg.getData().putString("exception", e.toString());
        		}
        	}
        }.start();
        
        // Bind the adapter to this view
        adapter = new ListTableAdapter(this);
        setListAdapter(adapter); 
        getListView().setOnScrollListener(this);
        
    }
	
	private void updateViewRecordsFound(int amountOfRecords) {
		TextView view = (TextView) findViewById(R.id.tableAmount);
		String plural = "";
		if (amountOfRecords > 1 || amountOfRecords == 0) {
			plural = "s";
		}
		String amountOfRecordsString = amountOfRecords + " tafel" + plural + " gevonden.";
		view.setText(amountOfRecordsString);
	}
	
	@SuppressLint("HandlerLeak")
	private Handler searchOutputHandler = new Handler() {
		public void handleMessage(Message msg) {
			String newData = msg.getData().getString("searchResult");
			JSONArray records = null;
			ArrayList<RestaurantTable> list = new ArrayList<RestaurantTable>();
			int amountOfRecordsFound = 0;
			try {
				JSONObject jsonObject = new JSONObject(newData);
				if (jsonObject.has("data") && jsonObject.has("msg") && jsonObject.has("status")) {
					// Connection to server was successful and data was received 
					if (jsonObject.get("status").toString().equals("200")) {
						records = jsonObject.getJSONArray("data");
						
						// Convert data into list of restaurants
						for (int i = 0; i < records.length(); i++) {
							try {
								JSONObject row = records.getJSONObject(i);
								if (row != null) {
									int tableId = row.optInt("ID");
									int tableSeats = row.optInt("Seats");
									String tableType = row.optString("Type");
									
									RestaurantTable newRestaurantTable = new RestaurantTable(tableId, tableSeats, tableType);
									list.add(newRestaurantTable);
									amountOfRecordsFound++;
								}
							} catch (Exception e) {}
						}
						
						// Update the GUI
						if (list.size() > 0) {
							try {
								adapter.setRestaurants(list);
								adapter.notifyDataSetChanged();
								progress.dismiss();
							} catch (Exception e) {
								Toast.makeText(messageContext, "GUI update exception: " + e.getMessage(), Toast.LENGTH_SHORT);
							}
						} else {
							// 0 results found
							adapter.setRestaurants(list);
							progress.dismiss();
						}
						updateViewRecordsFound(amountOfRecordsFound);
					} else {
						Toast.makeText(messageContext, "Backend server error no : " + jsonObject.get("status").toString(), Toast.LENGTH_SHORT).show();
						progress.dismiss();
					}
				} else {
					Toast.makeText(messageContext, "Faulty backend server response!", Toast.LENGTH_SHORT).show();
					progress.dismiss();
				}
			} catch (JSONException jsnE) {
				String errorMessage = "JSON Error: " + jsnE.getMessage();
				if (newData.equals("Error: No network")) {
					errorMessage = getResources().getString(R.string.no_network_connection);
				}
				Toast.makeText(messageContext, errorMessage, Toast.LENGTH_LONG).show();
				progress.dismiss();
			} catch (Exception e) {
				Toast.makeText(messageContext, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
				progress.dismiss();
			}
		}
	};
	
	public void onContentChanged() {
		super.onContentChanged();
		
		// Show message when no results are found
		View emptyView = findViewById(R.id.noResults);
		ListView list = getListView();
		list.setEmptyView(emptyView);
	}
	
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
		
		if (loadMore && visibleItemCount != totalItemCount) {
			adapter.count += visibleItemCount;
			adapter.notifyDataSetChanged();
		}
	}
	
	public void onListItemClick(ListView l, View v, int position, long id) {
		View selectedItem = v; 
		if (selectedItem != null) {
			selectedTable = (ResultsItemHolder) selectedItem.getTag();
			if (selectedTable != null) {
				
				final String restaurantTableId = selectedTable.restTableId.getText().toString();
				String restaurantTableSeats = selectedTable.restTableSeats.getText().toString();
				String restaurantTableType = selectedTable.restTableType.getText().toString();

				String message = "Tafel informatie:\n\nNummer: " + restaurantTableId + 
						"\nAantal plaatsen: " + restaurantTableSeats + 
						"\nType: " + restaurantTableType;
				
				AlertDialog.Builder builder = new AlertDialog.Builder(messageContext);
				builder.setMessage(message).setTitle(R.string.table_confirm_title);
				builder.setPositiveButton(R.string.lbl_reservation,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) 
							{
								Intent idIntent = new Intent(TableReservation.this, SelectMenuItem.class);
								Bundle newBundle = new Bundle(getIntent().getExtras());
								int tableID = Integer.parseInt(selectedTable.restTableId.getText().toString());
								newBundle.putInt(getResources().getString(R.string.key_table_id), tableID);
								idIntent.putExtras(newBundle);
						        startActivity(idIntent);
							}
						});
				builder.setNegativeButton(R.string.label_cancel, 
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) 
							{
								//Do Nothing
							}
						});
				
				AlertDialog newDialog = builder.create();
				newDialog.show();
			}
		}
	}


	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// Don't do anything
	}
	
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.top_navigation, menu);
		return true;
	}
	
	class ListTableAdapter extends BaseAdapter {
		Context context;
		private ArrayList<RestaurantTable> data;
		int count = 40;
		
		public ListTableAdapter(Context context) {
			this.context = context;
		}
		
		@Override
		public int getCount() {
			if (data != null)
				return data.size();
			else
				return 0;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// Custom results with custom view (SearchResultsItem)
			View row = convertView;
			ResultsItemHolder itemHolder = new ResultsItemHolder();
			
			if (convertView == null) {
				LayoutInflater inflater = ((Activity)context).getLayoutInflater();
				row = inflater.inflate(R.layout.reservation_tables_item, parent, false);	
				
				itemHolder.restTableId = (TextView) row.findViewById(R.id.result_restaurant_table_id_data);
				itemHolder.restTableSeats = (TextView) row.findViewById(R.id.result_restaurant_table_seats_data);
				itemHolder.restTableType = (TextView) row.findViewById(R.id.result_restaurant_table_type_data);
				
				row.setTag(itemHolder);
			} else {
				itemHolder = (ResultsItemHolder) row.getTag();
			}
			
			RestaurantTable restaurantTable = null;
			if (position < data.size()) {
				restaurantTable = data.get(position);
			}
			
			if (itemHolder != null) {
				if (restaurantTable != null) {
					itemHolder.restTableId.setText(Integer.toString(restaurantTable.getRestTableId()));
					itemHolder.restTableSeats.setText(Integer.toString(restaurantTable.getRestTableSeats()));
					itemHolder.restTableType.setText(restaurantTable.getRestTableType());
				} else {
					itemHolder.restTableId.setText("NoTableId" + position);
					itemHolder.restTableSeats.setText("NoSeatsAvailiable");
					itemHolder.restTableType.setText("NoTableTypeAvailiable");
				}
				
			}			
			return row;
		}
		
		public ArrayList<RestaurantTable> getRestaurants() { return data; }
		public void setRestaurants(ArrayList<RestaurantTable> newData) {
			data = newData;
		}
	}
	
	private static class ResultsItemHolder {
		public TextView restTableId;
		public TextView restTableSeats;
		public TextView restTableType;
	}

}
